package cn.zzf.algs.note.base.collection.v1;

import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.StdOut;

/**
 * @author GaoFeng2017
 * @date 2019/11/16 14:44
 */
public class ExpressionEval {

    public static void parse(String expression) {

        // ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) )

        expression = expression.replaceAll(" ", "");

        // 操作数栈
        Stack<Integer> numbers = new Stack<>();

        // 运算符栈
        Stack<Character> operators = new Stack<>();

        char[] chars = expression.toCharArray();

        for (char operator : chars) {
            switch (operator) {
                case '(':
                    break;
                case ')':
                    // 弹出运算符
                    Character character = operators.pop();
                    // 弹出操作数
                    Integer aNumber = numbers.pop();
                    Integer bNumber = numbers.pop();
                    // 计算，压入栈
                    Integer calculateResult = calculate(aNumber, bNumber, character);
                    numbers.push(calculateResult);
                    break;
                case '+':
                case '-':
                case '*':
                case '/':
                    operators.push(operator);
                    break;
                default:
                    numbers.push(operator - '0');
                    // 数字
            }
        }

        StdOut.println(operators);
        StdOut.println(numbers);

    }


    private static Integer calculate(Integer aNumber, Integer bNumber, Character operator) {

        int result = 0;

        switch (operator) {
            case '+':
                result = aNumber + bNumber;
                break;
            case '-':
                result = aNumber - bNumber;
                break;
            case '*':
                result = aNumber * bNumber;
                break;
            case '/':
                result = aNumber / bNumber;
                break;
            default:
                throw new IllegalArgumentException();
        }

        // 使用操作符号
        return result;

    }

}